/**
 * nghilt
 * 2011/09/26
 *
 * Copyright by N&N.,Inc
 */
package vn.nnn.shogi.quanco;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.ImageObserver;
import java.util.ArrayList;

import javax.swing.JApplet;

import at.com.vn.chess.util.CommonMethod;
import at.com.vn.chess.util.Const;

import vn.nnn.shogi.board.Board;

/**
 * 
 */
public abstract class QuanCo implements IQuanCo, Cloneable {

	protected Point toaDoNhaTu;

	public Image pic;
	public Image enemyPic;
	public int color;
	public Rectangle toaDo;
	public boolean isTuBinh;
	public boolean normalDirection;

	JApplet mainApplet;

	public QuanCo(Rectangle toaDo, int color, boolean normalDirection,
			JApplet mainApplet) {
		this.toaDo = toaDo;
		this.mainApplet = mainApplet;
		this.normalDirection = normalDirection;
		setColor(color);

		if (!normalDirection) {
			changePic();
		}

		setToaDoNhaTu();
	}

	public void setColor(int color) {
		this.color = color;
		String colorName = "";
		String enemyColorName = "";
		if (color == QUAN_DEN) {
			colorName = "Den";
			enemyColorName = "Trang";
		} else {
			colorName = "Trang";
			enemyColorName = "Den";
		}

		String picName = new StringBuilder().append(Const.IMAGE_DIR)
				.append(getClass().getSimpleName()).append(colorName)
				.append(Const.IMAGE_EXT).toString();

		pic = mainApplet.getImage(mainApplet.getCodeBase(), picName);

		enemyPic = mainApplet.getImage(
				mainApplet.getCodeBase(),
				new StringBuilder().append(Const.IMAGE_DIR)
						.append(getClass().getSimpleName())
						.append(enemyColorName).append(Const.IMAGE_EXT)
						.toString());
	}

	/**
	 * Hau het cac quan co deu co the phong cap tru tuong vang, vua va cac quan
	 * da phong cap
	 * 
	 * @return boolean value
	 */
	public boolean canUpgrade() {
		return true;
	}

	public void move(Rectangle destination) {
		toaDo = destination;
	}

	public void move(Board board, Rectangle destination, int foundedIdx,
			ArrayList<QuanCo> listQuanCo) {
		toaDo = destination;
	
		// Xu ly truong hop bat quan
		if (foundedIdx != Const.UNDEFINE_VALUE) {
	
			QuanCo foundedPiece = listQuanCo.get(foundedIdx);
	
			// tra ve nguyen dang truoc khi phong
			if (foundedPiece.getQuanTruocKhiPhong() != null) {
	
				listQuanCo.remove(foundedIdx);
				listQuanCo.add(foundedIdx, foundedPiece.getQuanTruocKhiPhong());
	
				foundedPiece = listQuanCo.get(foundedIdx);
			}
	
			foundedPiece.thanhQuanDoiPhuong(board, listQuanCo);
		}
	}

	public int getX() {
		return toaDo.x;
	}

	public int getY() {
		return toaDo.y;
	}

	public int getWidth() {
		return toaDo.width;
	}

	public int getHeight() {
		return toaDo.height;
	}

	public Image getPic() {
		return pic;
	}

	public int getEnemyColor() {
		if (color == QUAN_DEN) {
			return QUAN_TRANG;
		} else {
			return QUAN_DEN;
		}
	}

	public JApplet getMainApplet() {
		return mainApplet;
	}

	public void setToaDo(Rectangle toaDo) {
		this.toaDo = toaDo;
	}

	/**
	 * Ham nay van chua duoc toi uu Se duoc phat trien khi mo rong them tinh
	 * nang danh co voi may tinh Chuyen vao IQuanCo de tro thanh mot method truu
	 * tuong
	 * 
	 * @return
	 */
	public ArrayList<Rectangle> findAllPosibleMovement(Board board,
			ArrayList<QuanCo> listQuanCo) {

		Rectangle[][] banCo = board.getRealBoard();

		ArrayList<Rectangle> allPosibleMovement = new ArrayList<Rectangle>();
		QuanCo foundedPiece = null;
		Rectangle posibleMovement;

		// Tim o toan bo ban co
		for (int row = 0; row < Const.REAL_BOARD_ROW; row++) {
			for (int col = 0; col < Const.REAL_BOARD_COL; col++) {
				// Tim xem o do co quan nao dung san chua
				for (QuanCo co : listQuanCo) {
					if (co.toaDo.equals(banCo[row][col])) {
						foundedPiece = co;
					}
				}

				// Kiem tra xem quan nay co di chuyen duoc den day khong
				if (canMove(board, banCo[row][col], foundedPiece, listQuanCo)) {
					posibleMovement = banCo[row][col];
					allPosibleMovement.add(posibleMovement);
				}

				// reset
				foundedPiece = null;
			}
		}
		return allPosibleMovement;
	}

	public void thanhQuanDoiPhuong(Board board, ArrayList<QuanCo> listQuanCo) {

		isTuBinh = true;

		// Thanh tu binh
		thanhTuBinh(listQuanCo);

		// Nhot vao tu
		vaoTu(board);
	}

	private void thanhTuBinh(ArrayList<QuanCo> listQuanCo) {

		color = getEnemyColor();
		changePic();
	}

	protected void changePic() {
		// Dao nguoc hinh anh cua quan co
		Image tempPic = pic;
		pic = enemyPic;
		enemyPic = tempPic;
	}

	private void vaoTu(Board board) {
		Rectangle[][] vungBatQuan = board.getVungBatQuanCuaQuanDen();

		toaDo = vungBatQuan[toaDoNhaTu.x][toaDoNhaTu.y];

		// Point nhaTu = board.getToaDoNhaTu( toaDo );
		// board.tangSoLuongTuBinh( nhaTu );
	}

	public void release(Board board, Rectangle destination) {

		// Update trang thai ( so luong ) tu binh
		updateNhaTuSauKhiThaQuan(board);

		move(destination);

		// Khong con la tu binh
		isTuBinh = false;
	}

	public void updateNhaTuSauKhiThaQuan(Board board) {
		Point nhaTu = board.getToaDoNhaTu(toaDo);
		board.giamSoLuongTuBinh(nhaTu);
	}

	/**
	 * @return null neu quan do chua phong cap
	 */
	public QuanCo getQuanTruocKhiPhong() {
		return null;
	}

	public int getPositionInList(ArrayList<QuanCo> listQuanCo) {
		int idxChosen = Const.UNDEFINE_VALUE;
		for (int i = 0; i < listQuanCo.size(); i++) {
			if (listQuanCo.get(i).toaDo.equals(toaDo)) {
				idxChosen = i; // this identifies which piece has been
								// selected
				break;
			}
		}

		// add log
		if (idxChosen == Const.UNDEFINE_VALUE) {
			System.out
					.println("Loi khong the xay ra: khong tim thay quan nay tren ban co");
		}

		return idxChosen;
	}

	public boolean isTrongVungBatBuocPhongQuan(Board board,
			Rectangle destination) {
		return false;
	}

	/**
	 * Dieu kiem tha quan co ban la phai duoc tha trong ban co va o sap tha
	 * khong co quan co nao da dung o do
	 * 
	 * @param board
	 * @param destination
	 * @param listQuanCo
	 * @return
	 */
	public boolean isPassToBasicReleaseCondition(Board board,
			Rectangle destination, ArrayList<QuanCo> listQuanCo) {
		if (!board.isInRealBoard(destination)) {
			return false;
		}

		// Neu tha quan den mot o ma da ton tai san quan co
		for (int i = 0; i < listQuanCo.size(); i++) {
			if ((listQuanCo.get(i).isInSelectedArea(destination))) {
				return false;
			}
		}

		return true;
	}

	/**
	 * Dieu kien co ban de di chuyen mot con 1: Phai di trong ban co 2: Khong
	 * duoc an quan cua chinh minh 3: Khong duoc di den mot nuoc ma quan minh
	 * van se bi chieu
	 * 
	 * @param board
	 * @param destination
	 * @param foundedPiece
	 * @param listQuanCo
	 * @return
	 */
	public boolean isPassToBasicMoveCondition(Board board,
			Rectangle destination, QuanCo foundedPiece,
			ArrayList<QuanCo> listQuanCo) {

		boolean passed = true;

		// Khong the di ra khoi ban co
		if (!board.isInRealBoard(destination)) {
			return false;
		}

		// Khong the an quan cua minh
		int dummyFoundedIdx = Const.UNDEFINE_VALUE;
		if (foundedPiece != null) {
			if (foundedPiece.color == color) {
				passed = false;
			} else {
				dummyFoundedIdx = foundedPiece.getPositionInList(listQuanCo);
			}
		}

		// Kiem tra xem quan minh co dang bi chieu hay khong
		if (passed) {
			ArrayList<QuanCo> dummyList = CommonMethod
					.cloneListQuanCo(listQuanCo);
			QuanVua quanVua = CommonMethod.findQuanVua(dummyList, color);
			int dummyIdxChosen = getPositionInList(listQuanCo);

			QuanCo dummyCo = dummyList.get(dummyIdxChosen);
			dummyCo.move(board, destination, dummyFoundedIdx, dummyList);
			if (quanVua.isDangBiChieu(board, dummyList)) {
				passed = false;
			}
		}

		return passed;
	}

	public boolean isInSelectedArea(Rectangle rect) {
		// return toaDo == rect || (toaDo.x == rect.x && toaDo.y == rect.y);
		return toaDo.equals(rect);
	}

	public void drawQuanCo(Graphics g, ImageObserver imgObserver) {
		g.drawImage(pic, toaDo.x, toaDo.y, toaDo.width, toaDo.height,
				imgObserver);
	}

	@Override
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}
